package com.atguigu.gmall.common.exception;


import com.atguigu.gmall.common.execption.GmallException;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.result.ResultCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.Map;

//@ResponseBody
//@ControllerAdvice //这是一个异常处理器

@Slf4j
@RestControllerAdvice //这是一个异常处理器，出现任何异常，由他负责处理
public class GmallGlobalExceptionHandler {

    /**
     * 专门处理业务异常
     * @param ex
     * @return
     */
    @ExceptionHandler(GmallException.class)
    public Result handleBizException(GmallException ex){
        Integer code = ex.getCode();
        String message = ex.getMessage();


        Result<Object> fail = Result.fail();
        fail.setCode(code);
        fail.setMessage(message);
        return fail;
    }

    /**
     * 处理全局的校验异常
     * @param exception
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleValideException(MethodArgumentNotValidException exception){

        //1、到底哪些字段发生了什么错误。
        //所有校验的结果被封装到校验异常的 br 里面
        BindingResult bindingResult = exception.getBindingResult();

        //  email: 邮件不合法
        Map<String,String> args = new HashMap<>();
        for (FieldError error : bindingResult.getFieldErrors()) {
            String field = error.getField();
            String message = error.getDefaultMessage();
            args.put(field,message);
        }

        return Result.build(args, ResultCodeEnum.ARGS_INVALIDE);
    }


    /**
     * 处理其他系统运行期间异常
     */
    @ExceptionHandler(Throwable.class)
    public Result handleSysException(Throwable throwable){
        log.error("全局异常捕获：{}",throwable);
        Result<Object> fail = Result.fail();
        fail.setMessage(throwable.getMessage());
        return fail;
    }




}
